/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: 有点呆
 * Date: 2024-11-14
 * Time: 12:05
 */
import java.util.ArrayList;

public class OS {
    //申请、分配四个方法（1，2，3，4）、创建一个分区
    private ArrayList<Process>plist =new ArrayList<>();//进程队列
    private ArrayList<Area> alist= new ArrayList<>();//分区数组（队列）
    private int next=0;//循环首次适应算法的查找指针
    //分配四个方法
    public void distribution(int n,Process p) {
        switch (n) {
            case 1:
                FirstFit(p);//首次适应算法
                break;
            case 2:
                NextFit(p,next);//循环首次适应算法

                break;
            case 3:
                BrstFit(p);//最佳适应算法
                break;
            case 4:
                WorstFit(p);//最坏适应算法
                break;
            default:
                break;
        }
    }
    //	最坏适应算法(Worst  Fit)
//	查找时只要看第一个分区能否满足作业要求。
    private void WorstFit(Process p) {
        ArrayList<Area> a=new ArrayList<>();
        for(int i=0;i<alist.size()-1;i++) {
            for(int j=0;j<alist.size()-i-1;j++) {
                if(alist.get(j).getSize()<alist.get(j+1).getSize()) {
                    a.add(alist.get(j));
                    alist.set(j, alist.get(j+1));
                    alist.set(j+1, a.get(0));
                    a.remove(0);
                }
            }
        }
//		System.out.println(alist);
        int size=p.getAreaSize();//进程所需内存大小
        for(Area area:alist) {
            if(area.getState()==1&&area.commpare(size)) {
                p.setArea(new Area(area.getId(),size,area.getStartAddress(),2) );
                area.drawOut(size);
                break;
            }
        }
    }
    //	最佳适应算法(Best  Fit)
//	从全部空闲区中找出能满足作业要求的、且大小最小的空闲分区，
    private void BrstFit(Process p) {
        ArrayList<Area> a=new ArrayList<>();
        for(int i=0;i<alist.size()-1;i++) {
            for(int j=0;j<alist.size()-i-1;j++) {
                if(alist.get(j).getSize()>alist.get(j+1).getSize()) {
                    a.add(alist.get(j));
                    alist.set(j, alist.get(j+1));
                    alist.set(j+1, a.get(0));
                    a.remove(0);
                }
            }
        }
//		System.out.println(alist);
        int size=p.getAreaSize();//进程所需内存大小
        for(Area area:alist) {
            if(area.getState()==1&&area.commpare(size)) {
                p.setArea(new Area(area.getId(),size,area.getStartAddress(),2) );
                area.drawOut(size);
                break;
            }
        }
    }

    //	循环首次适应算法(Next  Fit)
    private void NextFit(Process p, int next2) {
        int size=p.getAreaSize();//进程所需内存大小
        int find=0;
        for(int i=next2;i<alist.size();i++) {
            if(find==alist.size()) {
                break;
            }
//			Area area=new Area(alist.get(i).getId(),alist.get(i).getSize(),alist.get(i).getStartAddress(),alist.get(i).getState());
            if(alist.get(i).getState()==1&&alist.get(i).commpare(size)) {
                p.setArea(new Area(alist.get(i).getId(),size,alist.get(i).getStartAddress(),2));
                alist.get(i).drawOut(size);
                next2=alist.get(i).getId()+1;
                if(next2==alist.get(alist.size()-1).getId()) {
                    next2=0;
                }
//				if(next2==10) {
//					next2=0;
//				}
                break;
            }
            if(i==alist.size()-1) {
                i=-1;
            }
            find++;
        }
        next=next2;
    }

    //	首次适应算法(First  Fit)
//	所有空闲区按其起始地址递增的次序排列。分配时 从链首开始顺序查找。
    public boolean FirstFit(Process p) {
        int size=p.getAreaSize();
        for (Area area : alist) {
            if(area.getState()==1&&area.commpare(size)) {
                //分区号+10 进程大小 开始地址 状态=忙
                p.setArea(new Area(area.getId(),size,area.getStartAddress(),2) );
                area.drawOut(size);
                return true;
            }
        }
        return false;
    }

    public ArrayList<Process> getPlist() {
        return plist;
    }
    public void setPlist(ArrayList<Process> plist) {
        this.plist = plist;
    }
    public ArrayList<Area> getAlist() {
        return alist;
    }
    public void setAlist(ArrayList<Area> alist) {
        this.alist = alist;
    }
    @Override
    public String toString() {
        return "OS [plist=" + plist + "\r\n alist=" + alist +"\r\n next=" + next + "]\r\n";
    }

}